package cn.wlh.learn.webmagic.pipeline;

import cn.hutool.core.util.StrUtil;
import cn.hutool.db.Entity;
import cn.hutool.db.Session;
import cn.hutool.db.ds.DSFactory;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import cn.hutool.setting.Setting;
import cn.hutool.system.SystemUtil;
import us.codecraft.webmagic.ResultItems;
import us.codecraft.webmagic.Task;
import us.codecraft.webmagic.pipeline.Pipeline;

import javax.sql.DataSource;
import java.util.Map;

/**
 * 默认以增量的形式，存入到数据库中。
 * 以url为主键。
 *
 *  @author code4crafter@gmail.com <br>
 * @since 0.2.0
 */
public class DBPipeline implements Pipeline {

    private final static Log logger = LogFactory.get();

    private final String dataName;
    private final String tableName;
    private final String keyName;
    private final Session session;
    private boolean insertOrUpdate = false;
    public DBPipeline(String dataName,String tableName, String keyName, Session session) {
        this.dataName = dataName;
        this.tableName = tableName;
        this.keyName = keyName;
        this.session = session;
    }


    public DBPipeline(String dataName,String tableName, String keyName) {
        this.dataName = dataName;
        this.tableName = tableName;
        this.keyName = keyName;

        // 防止初始化失败。
        Setting setting = new Setting();
        // mysql_password
        String username = SystemUtil.get("mysql_username","root" );
        setting.put("username",username );
        //
        String   password = SystemUtil.get("mysql_password","root" );
        setting.put("password",password  );
        //
        String ip = SystemUtil.get("server_ip","127.0.0.1" );
        String port = SystemUtil.get("mysql_port","3306" );
        String url = "jdbc:mysql://"+ip+":"+port+"/"+this.dataName+"?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&nullCatalogMeansCurrent=true";
        setting.put("url",url );
        // 暂时支持 mysql
        String driver = "com.mysql.cj.jdbc.Driver";
        setting.put("driver",driver );

        DSFactory dsFactory = DSFactory.create(setting);
        DataSource dataSource = dsFactory.getDataSource();
        // Session.create(dataSource); =》 这个报驱动找不到的错。
        this.session =  new Session( dataSource );

    }

    public DBPipeline(String tableName, String keyName) {
        this("caiji",tableName,keyName);
    }
    public DBPipeline(String tableName) {
        this(tableName,"id");
    }

    @Override
    public void process(ResultItems resultItems, Task task) {
        String url = resultItems.getRequest().getUrl();
        Map<String, Object> all = resultItems.getAll();
        try {
            Entity entity = new Entity(this.tableName);
            entity.put(this.keyName,url);
            entity.putAll(all);
            if (this.insertOrUpdate) {
                session.insertOrUpdate(entity,this.keyName);
            }else {
                String selectKeySql = StrUtil.format("select 1 from {} where {} = ?", this.tableName, this.keyName);
                // 查询是否之前插入过,
                if ( this.session.count(selectKeySql, url ) >0) {
                    return;
                }
                // 没有插入则插入.
                session.insert(entity);
            }

        } catch (Exception e) {
            logger.error("write db error", e);
            logger.warn("error url = [{}] \n data = [{}]",url,all);
            session.quietRollback();
        }finally {
//            session.close();
        }

        // 不关闭.
    }

    public String getTableName() {
        return tableName;
    }

    public String getKeyName() {
        return keyName;
    }

    public Session getSession() {
        return session;
    }

    public boolean isInsertOrUpdate() {
        return insertOrUpdate;
    }

    public void setInsertOrUpdate(boolean insertOrUpdate) {
        this.insertOrUpdate = insertOrUpdate;
    }
}
